package com.xdtech.sys.service.impl;

import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xdtech.common.exception.BusinessException;
import com.xdtech.core.dao.BaseDao;
import com.xdtech.core.model.BaseItem;
import com.xdtech.core.orm.Page;
import com.xdtech.core.orm.utils.BeanUtils;
import com.xdtech.sys.dao.TaskDao;
import com.xdtech.sys.model.Task;
import com.xdtech.sys.service.TaskService;
import com.xdtech.sys.task.SysJob;
import com.xdtech.sys.util.SysConstants;
import com.xdtech.sys.util.TaskUtils;
import com.xdtech.sys.vo.TaskItem;
import com.xdtech.web.model.Pagination;

/**
 * 
 * @author max.zheng
 * @create 2015-05-10 23:05:41
 * @since 1.0
 * @see
 */
@Service
public class TaskServiceImpl implements TaskService {
	@Autowired
	private TaskDao taskDao;
	@Autowired
	private BaseDao baseDao;
	@Autowired
	private Scheduler scheduler;
	
	public static Logger log = Logger.getLogger(TaskServiceImpl.class);  
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @param entity
	 */
	public void save(Task entity) {
		taskDao.save(entity);
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @param entity
	 */
	public void saveAll(List<Task> entities) {
		taskDao.saveAll(entities);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @param entity
	 */
	public void delete(Task entity) {
		taskDao.delete(entity);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @param id
	 */
	public void delete(Long id) {
		taskDao.delete(id);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @param id
	 * @return
	 */
	public Task get(Long id) {
		return taskDao.get(id);
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @return
	 */
	public List<Task> getAll() {
		return taskDao.getAll();
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @param pg
	 * @param values
	 * @return
	 */
	public Map<String, Object> loadPageAndCondition(Pagination pg,
			Map<String, String> values) {
		Map<String, Object> results = new HashMap<String, Object>();
		List<Object> tasks = null;
		long rows = 0;
		if (pg!=null) {
			Page<Task> page = taskDao.findPage(pg,"from Task order by createTime desc", values);
			tasks = BeanUtils.copyListProperties(
					TaskItem.class, page.getResult());
			rows = page.getTotalItems();
		}else {
			List<Task> taskList = taskDao.find("from Task order by id desc", values);
			tasks = BeanUtils.copyListProperties(
					TaskItem.class, taskList);
			rows = tasks.size();
		}
		results.put("total", rows);
		results.put("rows", tasks);
		return results;
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @param item
	 * @return
	 */
	public boolean saveOrUpdateTask(TaskItem item) {
		Task task = null;
		if (item.getId()==null) {
			task = new Task();
		}else {
			task = taskDao.get(item.getId());
		}
		//复制前台修改的属性
		BeanUtils.copyProperties(task, item);
		taskDao.save(task);
		stopOrStartTask(task.getStatus(), task);
		return true;
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @param taskId
	 * @return
	 */
	public TaskItem loadTaskItem(Long taskId) {
		Task task = taskDao.get(taskId);
		TaskItem taskItem = new TaskItem();
		BeanUtils.copyProperties(taskItem, task);
		return taskItem;
	}

	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @param id
	 * @return
	 */
	public boolean deleteTaskInfo(long id) {
		delete(id);
		return true;
	}
	
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @param newIds
	 * @return
	 */
	public boolean deleteTaskInfo(List<Long> taskIds) {
		for (Long id : taskIds) {
			Task task = get(id);
			stopOrStartTask("0", task);
			delete(task);
		}
		return true;
	}
	
	public Map<String, Object> loadPageDataByConditions(Pagination pg,
			BaseItem baseItem, String queryName) {
		Map<String, Object> results = new HashMap<String, Object>();
		Page page = baseDao.findPageByNamedQuery(pg, queryName,baseItem);
		results.put("total", page.getTotalItems());
		results.put("rows", page.getResult());
		return results;
	}
	/**
	 * @description
	 * @author max.zheng
	 * @create 2015-05-10 23:05:41
	 * @modified by
	 * @return
	 */
	@Override
	public List<TaskItem> loadItems() {
		List<Task> tasks = getAll();
		return TaskItem.createItems(tasks);
	}
	/* (非 Javadoc)
	 * startAllTasks
	 * <p>对override方法的补充说明，若不需要则删除此行</p>
	 * 
	 * @see com.xdtech.sys.service.TaskService#startAllTasks()
	 */
	@Override
	public void startAllTasks() 
	{
		List<TaskItem> taskItems = loadItems();
		try
		{
			for (TaskItem taskItem : taskItems)
			{
				if (SysConstants.TASK_RUN.equals(taskItem.getStatus()))
				{
					startOneTask(taskItem);
				}
			}
		}
		catch (Exception e)
		{
			throw new BusinessException(e.getMessage(),e);
		}
		
	}
	private void startOneTask(TaskItem taskItem) throws SchedulerException, ParseException
	{
		JobDetail jobDetail = new JobDetail();  
		jobDetail.setName(taskItem.getName());
		jobDetail.getJobDataMap().put("sysTask", taskItem);  
		jobDetail.setJobClass(SysJob.class);  
		scheduler.addJob(jobDetail, true);  
		
		CronTrigger cronTrigger = null;
		Trigger trigger = scheduler.getTrigger("cron_" +taskItem.getName(), taskItem.getTaskGroup());
		if (trigger!=null) {
			CronTrigger newCronTrigger = new CronTrigger("cron_" +taskItem.getName(), taskItem.getTaskGroup(), jobDetail.getName(), taskItem.getTaskGroup());  
			newCronTrigger.setCronExpression(taskItem.getCron());
			scheduler.rescheduleJob("cron_" +taskItem.getName(), taskItem.getTaskGroup(), newCronTrigger);
		}else {
			cronTrigger = new CronTrigger("cron_" +taskItem.getName(), taskItem.getTaskGroup(), jobDetail.getName(), taskItem.getTaskGroup());  
			cronTrigger.setCronExpression(taskItem.getCron());
			scheduler.scheduleJob(cronTrigger);
		}
		
	
	}
	
	public void testTask() {
		System.out.println("1111"+new Date());
	}
	/* (非 Javadoc)
	 * stopTasks
	 * <p>对override方法的补充说明，若不需要则删除此行</p>
	 * 
	 * @param taskIds
	 * @see com.xdtech.sys.service.TaskService#stopTasks(java.util.List)
	 */
	@Override
	public void stopOrStartTasks(List<Long> taskIds,String flag) throws Exception
	{
		List<Task> tasks = taskDao.get(taskIds);
		for (Task task : tasks)
		{
			stopOrStartTask(flag, task);
		}
		taskDao.saveAll(tasks);
	}
	/**
	 * 
	 * @author max.zheng
	 * @create 2015-5-12下午8:53:02
	 * @modified by
	 * @param flag
	 * @param task
	 * @throws SchedulerException
	 * @throws ParseException
	 */
	private void stopOrStartTask(String flag, Task task){
		try {
			if (SysConstants.TASK_STOP.equals(flag))
			{
				scheduler.unscheduleJob("cron_" + task.getName(), task.getTaskGroup());
				task.setStatus(SysConstants.TASK_STOP);
			}else if (SysConstants.TASK_RUN.equals(flag))
			{
				startOneTask(TaskItem.createItem(task));
				task.setStatus(SysConstants.TASK_RUN);
			}
		} catch (Exception e) {
			throw new BusinessException(e.getMessage(),e);
		}
		
	}

}
